package com.core.shared;

import com.core.model.user.Privilege;
import com.core.model.user.Privileges;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.usertype.EnhancedUserType;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Arrays;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: ZhongGang
 * Date: 14-4-24
 * Time: 上午11:34
 */
public class PrivilegesUserType implements EnhancedUserType, Serializable {
    private static final int[] SQL_TYPES = new int[]{Types.VARCHAR};
    private static final String DELIMITER = ",";

    @Override
    public String objectToSQLString(Object value) {
        throw new UnsupportedOperationException("Not yet implemented!");
    }

    @Override
    public String toXMLString(Object value) {
        return value.toString();
    }

    @Override
    public Object fromXMLString(String xmlValue) {
        throw new UnsupportedOperationException("Not yet implemented!");
    }

    @Override
    public int[] sqlTypes() {
        return SQL_TYPES;
    }

    @Override
    public Class returnedClass() {
        return Privileges.class;
    }

    @Override
    public boolean equals(Object x, Object y) throws HibernateException {
        if (x == y) {
            return true;
        }
        if (x == null || y == null) {
            return false;
        }
        Privileges dtx = (Privileges) x;
        Privileges dty = (Privileges) y;
        return dtx.equals(dty);
    }

    @Override
    public int hashCode(Object x) throws HibernateException {
        return x.hashCode();
    }

    @Override
    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException {
        String value = (String) StandardBasicTypes.STRING.nullSafeGet(rs, names, session, owner);
        if (value == null) {
            return new Privileges();
        }
        String[] values = value.split(DELIMITER);
        List<String> privileges = Arrays.asList(values);
        Privileges privilegesAsList = new Privileges();
        for (String privilege : privileges) {
            privilegesAsList.add(Privilege.valueOf(privilege));
        }
        return privilegesAsList;
    }

    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException {
        if (value == null) {
            StandardBasicTypes.STRING.nullSafeSet(st, null, index, session);
        } else {
            Privileges privileges = (Privileges) value;
            if (privileges.isEmpty()) {
                StandardBasicTypes.STRING.nullSafeSet(st, null, index, session);
            } else {
                String privilegeStr = "";
                for (Privilege privilege : privileges) {
                    privilegeStr += privilege.name() + DELIMITER;
                }
                privilegeStr = privilegeStr.substring(0, privilegeStr.lastIndexOf(DELIMITER));
                StandardBasicTypes.STRING.nullSafeSet(st, privilegeStr, index, session);
            }
        }
    }

    @Override
    public Object deepCopy(Object value) throws HibernateException {
        return value;
    }

    @Override
    public boolean isMutable() {
        return false;
    }

    @Override
    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) value;
    }

    @Override
    public Object assemble(Serializable cached, Object owner) throws HibernateException {
        return cached;
    }

    @Override
    public Object replace(Object original, Object target, Object owner) throws HibernateException {
        return original;
    }
}
